package com.loveshes.service;

import com.loveshes.AsyncOrderFacade;
import com.loveshes.constants.Constants;
import com.loveshes.dto.OrderInfo;
import com.loveshes.util.SleepUtil;
import org.apache.dubbo.config.annotation.DubboService;
import org.apache.dubbo.rpc.AsyncContext;
import org.apache.dubbo.rpc.RpcContext;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.math.BigDecimal;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

/**
 * @author wangz4
 * @date 2024/12/26 17:45
 */
@DubboService
public class AsyncOrderFacadeImpl implements AsyncOrderFacade {
    
    private static final Logger logger = LoggerFactory.getLogger(AsyncOrderFacadeImpl.class);
    
    @Override // 同步方式
    public OrderInfo queryOrderByIdSync(String id) {
        mockBusiness();
        OrderInfo orderInfo = new OrderInfo(
                "GeekDubbo",
                "服务方同步方式#" + id,
                new BigDecimal(129));
        logger.error("同步方式 traceId={} orderInfo={}", RpcContext.getServerAttachment().getAttachment(Constants.MDC_KEY_TRACE_ID), orderInfo);
        doSomething();
        return orderInfo;
    }
    
    @Override // 异步方式
    public OrderInfo queryOrderByIdAsync(String id) {
        ExecutorService cachedThreadPool = Executors.newCachedThreadPool();
        
        AsyncContext asyncContext = RpcContext.startAsync();
        cachedThreadPool.execute(() -> {
            asyncContext.signalContextSwitch();
            mockBusiness();
            
            OrderInfo orderInfo = new OrderInfo(
                    "GeekDubbo05",
                    "服务方异步方式之RpcContext.startAsync#" + id,
                    new BigDecimal(129));
            logger.error("异步方式 traceId={} orderInfo={}", RpcContext.getServerAttachment().getAttachment(Constants.MDC_KEY_TRACE_ID), orderInfo);
            asyncContext.write(orderInfo);
        });
        doSomething();
        return null;
    }
    
    @Override
    public CompletableFuture<OrderInfo> queryOrderByIdFuture(String id) {
        return CompletableFuture.supplyAsync(() -> {
            mockBusiness();
            OrderInfo orderInfo = new OrderInfo(
                    "GeekDubbo05",
                    "服务方异步方式之CompletableFuture#" + id,
                    new BigDecimal(129));
            logger.error("异步方式 traceId={} orderInfo={}", RpcContext.getServerAttachment().getAttachment(Constants.MDC_KEY_TRACE_ID), orderInfo);
            return orderInfo;
        });
    }
    
    private void mockBusiness() {
        SleepUtil.sleep(2000);
    }
    
    private void doSomething() {
        SleepUtil.sleep(2000);
    }
    
}
